﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Security;
using ChatJs.Lib;
using IDotNet;
using Microsoft.AspNet.SignalR;
using Polly;

namespace chatjs
{
    public class ChatHub : Hub, IChatHub
    {
        private const string UsersKey = "Users";
        private const string RoomsKey = "Rooms";
        private const string RoomFormat = "Room_{0}";
        private const string RoomMsgFormat = "RoomMsg_{0}";


        public int FromUserId
        {
            get
            {
                var auth = HttpContext.Current.User.Identity.Name;
                if (string.IsNullOrWhiteSpace(auth))
                {
                    throw new UnauthorizedAccessException();
                }
                return int.Parse(auth);
            }
        }
        public ChatHub()
        {
        }
        public List<ChatMessageInfo> GetMessageHistory(int? roomId, int? conversationId, int? otherUserId)
        {
            var keyId = RoomMsgFormat.FormatWith(roomId);
            return RedisHelper.GetList<ChatMessageInfo>(keyId);
        }

        public void SendMessage(int? roomId, int? conversationId, int? userToId, string message, string clientGuid)
        {
            var keyId = RoomMsgFormat.FormatWith(roomId);
            RedisHelper.AddList(keyId, new ChatMessageInfo()
            {
                ClientGuid = clientGuid,
                ConversationId = conversationId,
                DateTime = DateTime.UtcNow,
                Message = message,
                RoomId = roomId,
                Timestamp = Environment.TickCount,
                UserToId = userToId,
                UserFromId = FromUserId,
            });
        }

        public void SendTypingSignal(int? roomId, int? conversationId, int? userToId)
        {
            
        }

        public void EnterRoom(int roomId)
        {
            var key = RoomFormat.FormatWith(roomId);
            var user = RedisHelper.Get<ChatUserInfo>(UsersKey, FromUserId.ToString());
            user.Status=ChatUserInfo.StatusType.Online;
            RedisHelper.SetHash(key, user.Id.ToString(), user);
            var room = RedisHelper.Get<ChatRoomInfo>(RoomsKey, roomId.ToString());
            room.UsersOnline = room.UsersOnline + 1;
            RedisHelper.SetHash(RoomsKey, roomId.ToString(), room);
        }

        public void LeaveRoom(int roomId)
        {
            var key = RoomFormat.FormatWith(roomId);
            var user = RedisHelper.Get<ChatUserInfo>(UsersKey, FromUserId.ToString());
            user.Status = ChatUserInfo.StatusType.Offline;
            RedisHelper.SetHash(key, user.Id.ToString(), user);
            var room = RedisHelper.Get<ChatRoomInfo>(RoomsKey, roomId.ToString());
            room.UsersOnline = room.UsersOnline - 1;
            RedisHelper.SetHash(RoomsKey, roomId.ToString(), room);
        }

        public List<ChatUserInfo> GetUserList(int? roomId, int? conversationId)
        {
            var key = RoomFormat.FormatWith(roomId);
            return RedisHelper.GetAll<ChatUserInfo>(key);
        }

        public List<ChatRoomInfo> GetRoomsList()
        {
            if (!RedisHelper.KeyExists(RoomsKey))
            {
                RedisHelper.SetHash(RoomsKey, "1", new ChatRoomInfo()
                {
                    Id = 1,
                    Name = "Default",
                    UsersOnline = 0,
                });
            }
            return RedisHelper.GetAll<ChatRoomInfo>(RoomsKey);
            //return Policy.Handle<Exception>()
            //     .Retry(1, (ex, count) =>
            //     {
            //         CommFunc.Log.Error(ex);
            //     })
            //     .Execute(() =>
            //     {
                    
            //     });
        }

        //public Task OnConnected()
        //{
        //    return Task.FromResult(0);
        //}

        public Task OnDisconnected()
        {
            return Task.FromResult(0);
        }

        public ChatUserInfo GetUserInfo(int id)
        {
            return RedisHelper.Get<ChatUserInfo>(UsersKey, id.ToString());
        }
    }
}